package com.thitech.sif.socket;

import java.io.InputStream;

import com.thitech.sif.AbsExecutor;
import com.thitech.sif.Constant;
import com.thitech.sif.Executor;
import com.thitech.sif.ExtendMapKey;
import com.thitech.sif.ReqAndResContext;
import com.thitech.sif.context.AbsContext;
import com.thitech.sif.interceptor.InterceptorExecutor;
import com.thitech.sif.interceptor.InterceptorFactory;
import com.thitech.sif.utils.SocketUtil;

/**
 * Socket服务执行器，封装服务时直接使用该类，并通过该类传递服务调用所必须的数据给框架，且调用该类中的execute方法对服务客户端进行包装处理。
 * 
 * @author shisheng.lian
 * @date 2014-04-10
 *
 */
public class SocketExecutor extends AbsExecutor implements ISocketExecutor {
	
	public SocketExecutor() {
		super();
	}

	public SocketExecutor(String serviceId, String ticket, String businessId) {
		super(serviceId, ticket, businessId);
	}

	@Override
	public SocketBaseOutput execute(SocketBaseOutput output, SocketHelperForJar scktHelperForJar) {
		Exception rune = null;
		boolean exeFlag = true;
		try{
			validateInputParam(output,scktHelperForJar);
			exeFlag = InterceptorExecutor.invokeBefore(this);
			this.getExtDataMap().put(ExtendMapKey.BEFORE_INTERCEPTOR_EXECUTE_FLAG, exeFlag);
			if(exeFlag){
				SocketBaseOutput executeOutPut = scktHelperForJar.doExecute(this);
				if(null != executeOutPut){
					output = executeOutPut;
				}
			}
			ReqAndResContext.currentContext().setResponse(output.getResponseString());
		}catch(Exception e){
			rune = e;
		}finally{
			try{
				//给serviceDataHolder对象设置服务输入数据（针对提供第三方包Socket Client的封装）
				ReqAndResContext.currentContext().setRequest(scktHelperForJar.getInput(this));
				
				InterceptorExecutor.invokeAfter(this, output, rune);
			}catch(Exception e){
				//处理最终拦截器中出现的异常信息
				InterceptorExecutor.invokeLastFailInterceptor(
						InterceptorFactory.GLOBAL_DEFAULT_EXCEPTION_INTERCEPTOR, this, output, e);
			}
		}
		return output;
	}
	
	@Override
	public SocketBaseOutput execute(SocketBaseOutput output, SocketHelper scktHelper) {
		Exception rune = null;
		boolean exeFlag = true;
		try{
			validateInputParam(output,scktHelper);
			//给seviceDataHolder对象设置服务输入数据（针对通用Socket Client的封装）
			String requestString = scktHelper.doInput(this);
			ReqAndResContext.currentContext().setRequest(requestString);
			
			exeFlag = InterceptorExecutor.invokeBefore(this);
			this.getExtDataMap().put(ExtendMapKey.BEFORE_INTERCEPTOR_EXECUTE_FLAG, exeFlag);
			
			if(exeFlag){
				SocketBaseOutput executeOutPut = execute(requestString, this, scktHelper);
				if(null != executeOutPut){
					output = executeOutPut;
				}
			}
			
			ReqAndResContext.currentContext().setResponse(output.getResponseString());
		}catch(Exception e){
			rune = e;
		}finally{
			try{
				InterceptorExecutor.invokeAfter(this, output, rune);
			}catch(Exception e){
				//处理最终拦截器中出现的异常信息
				InterceptorExecutor.invokeLastFailInterceptor(
						InterceptorFactory.GLOBAL_DEFAULT_EXCEPTION_INTERCEPTOR, this, output, e);
			}
		}
		return output;
	}
	
	private SocketBaseOutput execute(String requestString, Executor executor, SocketHelper scktHelper) throws Exception {
		AbsContext ctx = executor.getContext();
		SocketUtil util = new SocketUtil(ctx.getHost(), ctx.getPort(), ctx.getCto(), ctx.getRto());
		InputStream in = util.send(requestString, ctx.getCharset());
		SocketBaseOutput output = scktHelper.getResult(in, executor);
		util.close();
		return output;
	}

	@Override
	public String getServiceType() {
		return Constant.SERVICE_TYPE_SOCKET;
	}
}
